package com.lanou3g.ptp.teachlink.service.impl;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.lanou3g.ptp.entity.Clazz;
import com.lanou3g.ptp.entity.Teacher;
import com.lanou3g.ptp.entity.Teachlink;
import com.lanou3g.ptp.entity.TeachlinkTeacher;
import com.lanou3g.ptp.exception.PtpException;
import com.lanou3g.ptp.organize.service.ClazzService;
import com.lanou3g.ptp.organize.service.MajorService;
import com.lanou3g.ptp.teacher.service.TeacherService;
import com.lanou3g.ptp.teachlink.mapper.TeachlinkMapper;
import com.lanou3g.ptp.teachlink.mapper.TeachlinkTeacherMapper;
import com.lanou3g.ptp.teachlink.service.TeachlinkService;
import com.lanou3g.ptp.utils.DateUtils;
import com.lanou3g.ptp.vo.TeachLinkParams;
import com.lanou3g.ptp.vo.TeachlinkVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Service(interfaceClass = TeachlinkService.class,timeout = 10000)
@Slf4j
public class TeachlinkServiceImpl implements TeachlinkService {
    @Autowired
    private TeachlinkMapper teachlinkMapper;

    @Autowired
    private TeachlinkTeacherMapper teachlinkTeacherMapper;

    @Reference
    private TeacherService teacherService;

    @Reference
    private MajorService majorService;

    @Reference
    private ClazzService clazzService;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Value("${REDIS_TEACHLINK_KEY_PREFIX}")
    private String REDIS_TEACHLINK_KEY_PREFIX;

    @Value("${REDIS_TEACHLINK_KEY_EXPIRE}")
    private Long REDIS_TEACHLINK_KEY_EXPIRE;

    @Override
    public PageInfo<Teachlink> findAll(Integer page, Integer size) {
        PageHelper.startPage(page, size);

        List<Teachlink> teachlinks = teachlinkMapper.findAll();

        return new PageInfo<>(teachlinks);
    }

    @Override
    public PageInfo<Teachlink> findByKeyword(Integer page, Integer size, String keyword) {
        PageHelper.startPage(page, size);

        List<Teachlink> byKeyword = teachlinkMapper.findByKeyword("%" + keyword + "%");

        return new PageInfo<>(byKeyword);
    }

    @Override
    public Teachlink findById(Long id) {
        return this.teachlinkMapper.findById(id);
    }

    @Transactional
    @Override
    public boolean insert(Long teacherId, TeachlinkVO teachlink) throws PtpException{
        log.info("新增教学环节, 接收数据: {}", teachlink);

        // 当前登录的老师id
        Teacher teacher = this.teacherService.findById(teacherId);
        // 专业id
        Long majorId = teacher.getMajorId();
        if (majorId == null) {
            throw new PtpException(301, "您没有权限创建教学环节");
        }
        // 专业名称
        String majorName = teacher.getMajorName();

        Teachlink tl = new Teachlink();
        BeanUtils.copyProperties(teachlink, tl);
        log.info("新增教学环节, 准备插入数据: {}", tl);

        // 关联专业id
        tl.setMajorId(majorId);
        tl.setMajorName(majorName);

        tl.setStatus(0);
        Date now = DateUtils.now();
        tl.setCreateTime(now);
        tl.setUpdateTime(now);

        // 插入教学环节
        this.teachlinkMapper.insert(tl);

        Long teachlinkId = tl.getId();
        // 所有的参与教师
        Long[] teachers = teachlink.getTeacherIds();
        log.info("新增教学环节, Service2: {}", teachlink);
        List<TeachlinkTeacher> tts = new ArrayList<>();
        for (Long id : teachers) {
            TeachlinkTeacher tt = TeachlinkTeacher.builder()
                    .teachlinkId(teachlinkId)
                    .teacherId(id)
                    .createTime(now)
                    .updateTime(now)
                    .build();
            tts.add(tt);
        }
        this.teachlinkTeacherMapper.addAll(tts);
        return true;
    }

    @Transactional
    @Override
    public void updateVO(Long teacherId, TeachlinkVO teachlink) throws PtpException {
        log.info("修改教学环节, 接收数据: {}", teachlink);
        // 当前登录的老师id
        Teacher teacher = this.teacherService.findById(teacherId);
        // 专业id
        Long majorId = teacher.getMajorId();
        if (majorId == null) {
            throw new PtpException(301, "您没有权限创建教学环节");
        }
        Date now = DateUtils.now();
        Teachlink tl = this.teachlinkMapper.findById(teachlink.getTeachlinkId());
        BeanUtils.copyProperties(teachlink, tl);
        tl.setUpdateTime(now);
        this.teachlinkMapper.updateById(tl);
        Long[] teachers = teachlink.getTeacherIds();
        List<TeachlinkTeacher> tts = new ArrayList<>();
        for (Long id : teachers) {
            TeachlinkTeacher tt = TeachlinkTeacher.builder()
                    .teachlinkId(teachlink.getTeachlinkId())
                    .teacherId(id)
                    .createTime(now)
                    .updateTime(now)
                    .build();
            tts.add(tt);
        }
        this.teachlinkTeacherMapper.deleteByTeachlinkId(teachlink.getTeachlinkId());
        this.teachlinkTeacherMapper.addAll(tts);
    }

    @Override
    public boolean updateById(Teachlink teachlink) {
        teachlink.setUpdateTime(new Date());
        int i = teachlinkMapper.updateById(teachlink);
        if (i > 0) {
            refreshCache(teachlink.getId());
            return true;
        } else {
            return false;
        }
    }

    @Transactional
    @Override
    public boolean deleteById(Long teachlinkId) {
        int x = this.teachlinkTeacherMapper.deleteByTeachlinkId(teachlinkId);
        int y = this.teachlinkMapper.deleteById(teachlinkId);
        return x > 0;
    }

    @Override
    public boolean deleteByIds(Long[] ids) {
        boolean deleteDBResult = teachlinkMapper.deleteByIds(ids) > 0;
        boolean deleteCacheResult = removeCaches(ids) > 0;
        return deleteDBResult && deleteCacheResult;
    }

    @Override
    public PageInfo<Teachlink> findByCondition(TeachLinkParams condition) {
        PageHelper.startPage(condition.getPage(), condition.getSize());
        // 如果传入了具体的某天查询日期, 那么就把seachdate这个条件置空
        if (condition.getPickdate() != null) {
            condition.setSearchdate(null);
        }
        List<Teachlink> items = this.teachlinkMapper.findByCondition(condition);
        return new PageInfo<>(items);
    }

    @Override
    public List<Teachlink> findByClazzId(Long clazzId) {
        Clazz clazz = clazzService.findById(clazzId);
        String grade = clazz.getGrade();
        return teachlinkMapper.findByMajorIdAndGrade(clazz.getMajorId(), grade);
    }

    @Override
    public TeachlinkVO findBodyById(Long teachlinkId) {
        Teachlink tl = this.teachlinkMapper.findById(teachlinkId);
        TeachlinkVO vo = new TeachlinkVO();
        BeanUtils.copyProperties(tl, vo);
        List<Long> teacherIds = this.teachlinkTeacherMapper.findTeacherIdsByTeachlinkId(teachlinkId);
        vo.setTeacherIds(teacherIds.toArray(new Long[0]));
        return vo;
    }

    private Teachlink refreshCache(Long id) {
        Teachlink teachlink = teachlinkMapper.findById(id);
        String key = REDIS_TEACHLINK_KEY_PREFIX + id;
        String teachlinkJson = JSON.toJSONString(teachlink);
        redisTemplate.opsForValue().set(key, teachlinkJson, REDIS_TEACHLINK_KEY_EXPIRE, TimeUnit.DAYS);
        return teachlink;
    }

    private Long removeCaches(Long[] ids) {
        List<String> keys = new ArrayList<>();
        for (Long id : ids) {
            keys.add(REDIS_TEACHLINK_KEY_PREFIX + id);
        }
        return redisTemplate.delete(keys);
    }

}
